package cn.tedu.tmall.admin.mall.service.impl;

import cn.tedu.tmall.admin.mall.dao.cache.ICategoryCacheRepository;
import cn.tedu.tmall.admin.mall.dao.persist.repository.ICategoryRepository;
import cn.tedu.tmall.admin.mall.pojo.entity.Category;
import cn.tedu.tmall.admin.mall.pojo.param.CategoryAddNewParam;
import cn.tedu.tmall.admin.mall.pojo.vo.CategoryListLtemVO;
import cn.tedu.tmall.admin.mall.pojo.vo.CategoryStandardVO;
import cn.tedu.tmall.admin.mall.service.ICategoryService;
import cn.tedu.tmall.common.enumerator.ServiceCode;
import cn.tedu.tmall.common.ex.ServiceException;
import cn.tedu.tmall.common.pojo.vo.CategoryListVO;
import cn.tedu.tmall.common.pojo.vo.PageData;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;


@Service
//Transactional事务的注解
@Transactional
public class CategoryServiceImpl implements ICategoryService {
    @Autowired
    //自动装配
    private ICategoryRepository categoryRepository;

    @Autowired
    private ICategoryCacheRepository categoryCacheRepository;

    // 新增类别
    @Override
    public void addNew(CategoryAddNewParam categoryAddNewParam) {
        CategoryStandardVO parentCategory = null;
        //判断parentId的值是否不为0
        Long parentId = categoryAddNewParam.getParentId();
        if (parentId != 0) {
            //是: 调用Repository根据parentId查询父级类别的详情
            parentCategory = categoryRepository.getStandardById(parentId);
            //-- 判断查询结果是否为null
            if (parentCategory == null) {
                // -- 是: 抛出异常
                throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, "父级类别不存在!");
            } else {
                // -- 否:判断父级类别的enable是否为0
                if (parentCategory.getEnable() == 0) {
                    // -- -- 是：抛出异常
                    throw new ServiceException(ServiceCode.ERROR_CONFLICT, "父级类别已经被禁用!");
                }
            }
        }

        // 从参数中获取本次尝试新增的类别的名称
        String name = categoryAddNewParam.getName();
        // 调用Repository根据名称统计数量
        int countByName = categoryRepository.countByName(name);
        // 判断统计结果是否大于0
        if (countByName > 0) {
            // 是：抛出异常
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, "类别名称已经被占用!");
        }

        //确定depth的值: 判断parentId的值是否为0
        Integer depth;
        if (parentId == 0) {
            //是: depth固定为1
            depth = 1;
        } else {
            //否: depth父级类别的depth+1
            depth = parentCategory.getDepth() + 1;
        }

        //创建实体(Category)类
        Category category = new Category();
        //将参数的各属性复制到实体对象中
        BeanUtils.copyProperties(categoryAddNewParam, category);
        //补全实体对象中的属性,depth,isParent(0)
        category.setDepth(depth);
        category.setIsParent(0);
        //调用Repository执行插入数据(实体)
        int rows = categoryRepository.insert(category);
        if (rows != 1) {
            throw new ServiceException(ServiceCode.ERROR_INSERT, "服务器忙,请稍后再试!");
        }

        // 当父级类别存在，且父级类别的isParent为0时，需要将父级类别的isParent从0改为1
        if (parentCategory != null && parentCategory.getParentId() == 0) {
            Category updateParentCategory = new Category();
            updateParentCategory.setId(parentId);
            updateParentCategory.setIsParent(1);
            categoryRepository.updateById(updateParentCategory);
            if (rows != 1) {
                throw new ServiceException(ServiceCode.ERROR_INSERT, "服务器忙,请稍后再试!");
            }
        }
    }

    // 根据ID查询类别
    @Override
    public CategoryStandardVO selectById(Long id) {
        CategoryStandardVO standardById = categoryRepository.getStandardById(id);
        //当查询到的数据为null时,则抛出异常
        if (standardById == null) {
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, "查询类别详情失败，类别数据不存在！");
        }
        return standardById;
    }

    // 根据父级查询其子级列表,使用分页查询
    @Override
    public PageData<CategoryListLtemVO> listByParent(Long parentId, Integer pageNum, Integer pageSize) {
        return categoryRepository.listByParent(parentId, pageNum, pageSize);
    }

    @Override
    public void rebuildCache() {
        categoryCacheRepository.deleteAll();
        Long parentId = 0L;
        List<CategoryListVO> list = categoryRepository.listByParentId(parentId);
        categoryCacheRepository.saveCategoryState(parentId, list);
        callRecursion(list);
    }

    private void callRecursion(List<CategoryListVO> categoryList) {
        for (CategoryListVO Category : categoryList) {
            Long id = Category.getId();
            List<CategoryListVO> list = categoryRepository.listByParentId(id);
            if (list.size() > 0) {
                categoryCacheRepository.saveCategoryState(id, list);
                callRecursion(list);
            }
        }
    }

}
